package com.enation.app.javashop.buyer.api.distribution;

import com.enation.app.javashop.core.base.CachePrefix;
import com.enation.app.javashop.core.distribution.exception.DistributionErrorCode;
import com.enation.app.javashop.core.distribution.exception.DistributionException;
import com.enation.app.javashop.core.distribution.model.dos.ShareDO;
import com.enation.app.javashop.core.distribution.service.DistributionManager;
import com.enation.app.javashop.core.distribution.service.ShortUrlManager;
import com.enation.app.javashop.core.distribution.util.ShortUrlGenerator;
import com.enation.app.javashop.core.member.model.dos.ConnectDO;
import com.enation.app.javashop.core.member.model.enums.ConnectTypeEnum;
import com.enation.app.javashop.core.member.model.vo.Auth2Token;
import com.enation.app.javashop.core.member.service.MemberInviterManager;
import com.enation.app.javashop.framework.cache.Cache;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.security.model.Buyer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Random;

/**
 * 小程序分销控制器
 */
@RestController
@RequestMapping("/distribution/minipro")
@Api(description = "小程序分销api")
public class MiniproDistributionController {

    @Autowired
    @Qualifier("memberDaoSupport")
    private DaoSupport memberDaoSupport;

    @Autowired
    private DistributionManager distributionManager;
    @Autowired
    private Cache cache;

    private final Log logger = LogFactory.getLog(this.getClass());


    @ApiOperation("生成分享标识键， 分享者必须登录")
    @GetMapping(value = "/create-share")
    @ApiImplicitParam(name = "share_url", value = "分享的url", required = true, paramType = "query", dataType = "String")
    public String createShare(String shareUrl) {
        Buyer buyer = UserContext.getBuyer();
        if (buyer == null) {
            throw new DistributionException(DistributionErrorCode.E1001.code(), DistributionErrorCode.E1001.des());
        }

        String uuid = buyer.getUuid();
        Integer memberId = buyer.getUid();

        String availableShareKey = null;
        String shortUrl = shareUrl + "?member_id=" + memberId;
        ShareDO shareDO = distributionManager.getByMemberIdAndUrl(memberId, shortUrl);
        if(shareDO == null){
            String[] shortUrls = ShortUrlGenerator.getShortUrl(shortUrl);
            for (String shareKey : shortUrls) {
                ShareDO existShareDO = distributionManager.getByShareKey(shareKey);
                if(existShareDO == null){
                    availableShareKey = shareKey;
                    break;
                }
            }

            if(availableShareKey == null){
                availableShareKey = String.valueOf(new Random().nextInt(1000000) + 100000);
                logger.error("分享标识键生成失败，重新生成随机数");
            }

            distributionManager.createShare(uuid, memberId, availableShareKey, shortUrl);
        }else{
            availableShareKey = shareDO.getShareKey();
        }
        logger.debug("分享标识键" + availableShareKey);
        return availableShareKey;
    }


    /**
     * 访问分享标识
     */
    @ApiOperation("访问分享链接")
    @GetMapping(value = "/visit")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "share_key", value = "分享标识", required = false, paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "visit_type", value = "访问类型，1分享 2直播", required = false, paramType = "query", dataType = "String")
    })
    public String visit(@ApiIgnore String shareKey, @ApiIgnore Integer visitType, @RequestHeader(required = false) String uuid) {
        // 分享人的会员id
        Integer sharerMemberId = getShareMemberId(shareKey, visitType);
        if (sharerMemberId != null && uuid != null) {
            logger.debug("访问分享链接" + uuid);
            Auth2Token auth2Token = (Auth2Token) cache.get(CachePrefix.CONNECT_LOGIN.getPrefix() + uuid);
            if (auth2Token != null) {
                String opneId = auth2Token.getOpneId();

                String sql = "select * from es_connect where open_id = ? and union_type = ?";
                ConnectDO connect = this.memberDaoSupport.queryForObject(sql, ConnectDO.class, opneId, ConnectTypeEnum.WECHAT.value());
                if(connect == null){
                    // 新用户注册 关系绑定
                    this.newRegisterBind(sharerMemberId, uuid, visitType);
                }else {
                    Integer currentMemberId = connect.getMemberId();

                    // 忽略本人访问
                    if (currentMemberId.equals(sharerMemberId)) {
                        return "忽略本人访问";
                    }

                    // 处理关系
                    distributionManager.handleShareRelationship(currentMemberId, sharerMemberId);
                }
            }else{
                this.newRegisterBind(sharerMemberId, uuid, visitType);
            }
            return "访问标记成功";
        }
        return "分享人会员id为空或uuid为空";
    }


    // 获取分享人会员id
    private Integer getShareMemberId(String shareKey, Integer visitType){
        if(visitType == null || visitType == 1){
            ShareDO shareDO = distributionManager.getByShareKey(shareKey);
            if(shareDO != null){
                return shareDO.getMemberId();
            }
        }else if(visitType == 2){
            String sql = "select * from es_connect where open_id = ? and union_type = ?";
            ConnectDO shareConnect = this.memberDaoSupport.queryForObject(sql, ConnectDO.class, shareKey, ConnectTypeEnum.WECHAT.value());
            if(shareConnect != null){
                return shareConnect.getMemberId();
            }
        }else{
            ShareDO shareDO = distributionManager.getByShareKey(shareKey);
            if(shareDO != null){
                return shareDO.getMemberId();
            }
        }
        return null;
    }

    /**
     * 新用户注册 关系绑定
     */
    private void newRegisterBind(Integer sharerMemberId, String uuid, Integer visitType){
        logger.debug("邀请人注册建立关系等待注册:" + sharerMemberId + "," + uuid);

        // 处理邀请人注册
        // connect为空表示用户可能是新用户 但是也可能注册过之后删除了小程序 consumer中会校验重复注册
        Object oldSharerMemberId = cache.get(MemberInviterManager.PREFIX + uuid);
        logger.debug("上一次访问的注册关系是:" + oldSharerMemberId + ",本次更新关系是:" + sharerMemberId + "," + uuid);
        cache.put(MemberInviterManager.PREFIX + uuid, sharerMemberId);
        cache.put(MemberInviterManager.CHANNEL + uuid, visitType);
        cache.put(ShortUrlManager.PREFIX + uuid, sharerMemberId);
    }

}
